/*!
 * SimpleUI javascript UI library
 * Copyright 2012, simpleui.org
 * Released under the MIT, BSD, and GPL Licenses.
 * More information: http://simpleui.org/
 * version : 2.0
 */

if (typeof Simple == "undefined") {
    var Simple = {};
}


(function(S) {
    
    S.isPlainObject = jQuery.isPlainObject;
    S.isArray = jQuery.isArray;
    S.uuid = 0;

    /**
     * 拷贝一个对象到另外一个对象上，如果只有一个参数，那个这个对象的属性或者方法将被添加到Simple上。
     * @method mixin
     * @param {Object} dest 源对象
     * @param {Object} prop 拷贝的对象
     * @return {Object} dest 修改后的dest对象
     */
    S.mixin = function(dest, prop) {
        if (!prop) {
            prop = dest
            dest = S;
        }
        for (var key in prop) {
            dest[key] = prop[key];
        }
        return dest;
    };

    S.mixinIf = function(dest, prop) {
        if (!prop) {
            prop = dest
            dest = S;
        }
        for (var key in prop) {
            if (!dest[key]) {
                dest[key] = prop[key];
            }
        }
        return dest;
    };
})(Simple);;
(function(S) {
	S.mixin({
		/**
		 * 遍历一个数组或者对象，并执行回调函数
		 * @method each
		 * @param {Object | Array} object 被遍历的对象
		 * @param {Function} callback 执行的回调函数
		 * @param {Object} conext 回调函数内部的作用域
		 * @return {Object} object 被遍历的对象
		 */
		each : function(object, callback, context) {
			var name, i = 0, length = object.length;
			if (length === undefined) {
				for (name in object) {
					if (callback.call(context || object[name], object[name], name) === false) {
						break;
					}
				}
			} else {
				for (var value = object[0]; i < length && callback.call(context || object[name], value, i) !== false; value = object[++i]) {
				}
			}
			return object;
		},
		/**
		 * 声明一个命名空间
		 *  <p>
		 *  <code>
		 *  Simple.namespace("Simple.dd");
		 *  Simple.dd.Drag=function(){}
		 *  </code>
		 *  </p>
		 * @method namespace
		 * @param {string} arguments
		 * @return {object} o 根据给出的字符串创建的对象
		 */
		namespace : function() {
			var a = arguments, o = this, i = 0, j, d, arg;
			for (; i < a.length; i++) {
				arg = a[i];
				if (arg.indexOf(".")) {
					d = arg.split(".");
					for ( j = (d[0] == 'Simple') ? 1 : 0; j < d.length; j++) {
						o[d[j]] = o[d[j]] || {};
						o = o[d[j]];
					}
				} else {
					o[arg] = o[arg] || {};
				}
			}
			return o;
		},
		/**
		 * 在控制台输出信息
		 * @method log
		 * @param {string} msg 需要输出的内容
		 */
		log : function(msg) {
			if (window.console && console.log) {
				console.log.apply(this, msg);
			}
		}
	});

	//size
	S.mixin({
		/**
		 * 获取当前页面的宽高(加上滚动条部分)
		 * @method getDoc
		 * @return {Object} Object.h 高度
		 * @return {Object} Object.w 宽度
		 */
		getDoc : function() {
			return {
				h : Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight),
				w : Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth)
			}
		},
		/**
		 * 获取当前页面的可视宽高
		 * @method getClient
		 * @return {Object} Object.h 高度
		 * @return {Object} Object.w 宽度
		 */
		getClient : function() {
			return {
				h : document.documentElement.clientHeight,
				w : document.documentElement.clientWidth
			}
		},
		/**
		 * 获取当前页面的可视宽高
		 * @method getSize
		 * @param el {Object} 需要后去宽高的HTML对象
		 * @param isModal {Boolean} 是否获取整个高度(加上滚动条部分)
		 * @return {Object} Object.h 高度
		 * @return {Object} Object.w 宽度
		 */
		getSize : function(el, isModal) {
			if (!( el instanceof jQuery)) {
				el = $(el);
			}
			if (el.is("body")) {
				if (isModal) {
					return this.getDoc();
				} else {
					return this.getClient();
				}
			} else {
				return {
					h : el.outerHeight(),
					w : el.outerWidth()
				}
			}
		}
	});

	/**
	 * 获取对象位置信息
	 * @module Simple.position
	 */
	S.position = {
		/**
		 * 设置某个对象相对参考对象的位置
		 * @method at
		 * @param config {Object}
		 * @param config.node {Object} 需要设置位置的对象
		 * @param config.referNode {Object} 相对对象
		 * @param config.points {String} 可选参数(cc | rc | bc | lc)
		 * @param config.offset {String} '0,5'
		 */
		at : function(config) {
			var node = config.node, referNode = config.referNode, points = config.points || 'cc', offset = config.offset || '0 0';
			node = $(node);
			offset = offset.split(' ');
			if (node.css("position") == "static") {
				node.css("position", "absolute");
			}
			var rfOffset = $(referNode).offset(), w = node.outerWidth(), h = node.outerHeight(), t, l, rfw = S.getSize(referNode).w, rfh = S.getSize(referNode).h;
			if ( typeof points == "string") {
				switch (points) {
					case "cc":
						t = rfOffset.top + (rfh - h) / 2;
						l = rfOffset.left + (rfw - w) / 2;
						break;
					case "rc":
						t = rfOffset.top + (rfh - h) / 2;
						l = rfOffset.left + rfw;
						break;
					case "bc":
						t = rfOffset.top + rfh;
						l = rfOffset.left + (rfw - w) / 2;
						break;
					case "lc":
						t = rfOffset.top + (rfh - h) / 2;
						l = rfOffset.left - w;
						break;
					case "tc":
						t = rfOffset.top - h;
						l = rfOffset.left + (rfw - w) / 2;
						break;
				}
			}
			t = t + offset[1];
			l = l + offset[0];
			node.css({
				top : t,
				left : l
			});
		},
		/**
		 * 让某个元素 相对body局中
		 * @method atBody
		 * @param node {Object} 需要获取位置的对象
		 */
		atBody : function(node) {
			var node = $(node), pos = node.css("position"), doc = Simple.getSize(document.body);
			if (pos == "fixed") {
				node.css({
					top : (doc.h - node.height()) / 2,
					left : (doc.w - node.width()) / 2
				});
			} else if (pos == "absolute") {
				node.css({
					top : (doc.h - node.height()) / 2 + Math.max(document.documentElement.scrollTop, document.body.scrollTop),
					left : (doc.w - node.width()) / 2
				});
			}
		}
	};

	S.mixin({
		/**
		 * 获取对象的绝对位置
		 * @method getRealPos
		 * @param {Object} element 需要获取位置的对象
		 * @return {Object} 返回对象的top, left 值
		 */
		getAbsPos : function(element) {
			var position = element.css("position"), top, left, parentOffset, offset = element.offset(), right, bottom;
			if (position == "static") {
				element.css("position", "relative");
				top = 0;
				left = 0;
			} else if (position == "absolute") {
				var parent = element.parent()
				while (parent.css("position") == "static" && !parent.is("body")) {
					parent = parent.parent();
				}
				parentOffset = parent.offset();
				top = offset.top - parentOffset.top;
				left = offset.left - parentOffset.left;
			} else if (position == "fixed") {
				top = parseFloat(element.css("top"));
				left = parseFloat(element.css("left"));
				if (isNaN(top)) {
					top = offset.top - Math.max(document.documentElement.scrollTop, document.body.scrollTop);
				}
				if (isNaN(left)) {
					left = offset.left;
				}
			} else if (position == "relative") {
				top = parseFloat(element.css("top"));
				left = parseFloat(element.css("left"));
				right = parseFloat(element.css("right"));
				bottom = parseFloat(element.css("bottom"));
				if (isNaN(top)) {
					if (!isNaN(bottom)) {
						top = -bottom
					} else {
						top = 0;
					}
				}
				if (isNaN(left)) {
					if (!isNaN(right)) {
						left = -right
					} else {
						left = 0;
					}
				}
			}

			return {
				left : left,
				top : top
			}
		},

		/**
		 * 获取元素的 left top right bottom
		 * @method getCoordinates
		 * @param {Object} element 需要获取位置的对象
		 * @return {Object} 返回对象的left top right bottom值
		 */
		getCoordinates : function(element) {
			var coor = {};
			element = $(element);
			if (element.length < 1) {
				return;
			}
			var offset = element.offset(), right = element.outerWidth() + offset.left, bottom = element.outerHeight() + offset.top;

			S.mixin(coor, {
				right : right,
				bottom : bottom
			}, offset);

			return coor;
		},
		/**
		 * 获取浏览器窗口滚动条位置
		 * @method getWinScroll
		 * @return {Object} 返回滚动条的值 x,y
		 */
		getScroll : function() {
			return {
				x : Math.max(document.documentElement.scrollLeft, document.body.scrollLeft),
				y : Math.max(document.documentElement.scrollTop, document.body.scrollTop)
			}
		}
	});

	//cookie
	S.namespace('cookie');
	/**
	 * cookie模块负责cookie的读写操作
	 * @module cookie
	 */
	S.mixin(S.cookie, {
		/**
		 * 获取cookie的值
		 * @method get
		 * @param {String} name
		 * @return cookie的值
		 */
		get : function(name) {
			var cookieValue = "";
			var search = name + "=";
			if (document.cookie.length > 0) {
				offset = document.cookie.indexOf(search);
				if (offset != -1) {
					offset += search.length;
					end = document.cookie.indexOf(";", offset);
					if (end == -1)
						end = document.cookie.length;
					cookieValue = unescape(document.cookie.substring(offset, end));
				}
			}
			return cookieValue;
		},
		/**
		 * 设置cookie的值
		 * @method set
		 * @param {String} name
		 * @param {String} value
		 * @param {Number} hours
		 */
		set : function(name, value, hours) {
			var expire = "";
			if (hours != null) {
				expire = new Date((new Date()).getTime() + hours * 3600000);
				expire = "; expires=" + expire.toGMTString();
			}
			document.cookie = name + "=" + escape(value) + expire + ";path=/";
		}
	});
	/**
	 * 将Simple下的插件桥接到jQuery
	 * @method bridgeTojQuery
	 * @param methodName {String} 插件名称
	 * @param widget {Object} 对应的插件
	 */
	S.bridgeTojQuery = function(methodName, widget) {
		var methodArray = methodName.split(",");
		jQuery.each(methodArray, function(i, n) {
			jQuery.fn[n] = function(config) {
				return this.each(function() {
					if (config == "destroy") {
						if (jQuery.data(this, "widget-" + n)) {
							jQuery.data(this, "widget-" + n).destroy();
							$(this).removeData("widget-" + n);
							return;
						} else {
							return true;
						}
					}
					config = config || {};
					config = S.mixin(config, {
						node : this
					});
					//不要重复绑定
					if (jQuery.data(this, "widget-" + n)) {
						return;
					}
					var widgetInc = new widget(config);
					jQuery.data(this, "widget-" + n, widgetInc);
				});
			}
		});
	};
})(Simple);
;
(function(S) {
	//declare
	var _crackName = function(name) {
		var index = name.lastIndexOf("."), clsName, o, args;
		if (index != -1) {
			args = name.substring(0, index);
			o = S.namespace(args);
			clsName = name.substring(index + 1, name.length);
		} else {
			clsName = name;
			o = S;
		}
		return {
			clsName : clsName,
			namespace : o
		};
	}
	S.mixin({
		/**
		 * 设置一个类为另外一个类的子类，可以使用instanceof判断之间的关系
		 * @method extend
		 * @param {object} subCls 用于继承的子类
		 * @param {object} superCls 被继承的父类
		 * @return {object} subCls 返回子类
		 */
		extend : function(subCls, superCls) {
			var F = function() {
			}, subClsProp;
			F.prototype = superCls.prototype;
			subClsProp = subCls.prototype = new F();
			subCls.prototype.constructor = subCls;
			subCls.superclass = superCls.prototype;
			return subCls;
		},
		/**
		 * 定义一个基础类，并且遍历指定的对象，拷贝到类的原型链上，并且调用原型链上的init的方法进行初始化。
		 * 如果指定父类，则该类会继承于这个父类，并且可以使用inherit来便捷调用父级方法.
		 *     Simple.declare('Animal',{
		 *         getName:function(){
		 *             return 'animal';
		 *         }
		 *     });
		 *     Simple.declare('Bird',Simple.Animal,{
		 *         getName:function(){
		 *             var superResult = this.inherit(arguments);
		 *             return superResult + ' bird';
		 *         }
		 *     });
		 *     console.log(new Simple.Bird().getName());//will console animal bird;
		 * @method declare
		 * @param {String} subCls
		 * @param {Function} superCls
		 * @param {Object} props
		 * @return 定义后的构造函数
		 */
		declare : function(subCls, superCls, props) {
			//参数判断
			if (!props) {
				props = superCls;
				superCls = null;
			}

			var clsInfo = _crackName(subCls);

			//生成构造函数
			subCls = clsInfo.namespace[clsInfo.clsName] = function(config) {
				S.mixin(this, config);
				//如果存在父类,父类构造函数先执行
                //循环执行父级的构造函数
				if (subCls.base) {
					for(var i=0;i<subCls.base.length;i++){
                        subCls.base[i].apply(this,arguments);
                    }
				}
				props.init && props.init.apply(this, arguments);
                


                if(this.postscript){
                    this.postscript(arguments);
                }
			}
			//继承
			if (superCls) {
				S.extend(subCls, superCls);
                subCls.base = [];
                if (superCls.base) {
                    S.each(superCls.base, function(item){
                        subCls.base.push(item);
                    });
                }
                subCls.base.push(subCls.superclass.init);
			}

			//拷贝对象到subCls原型链
			//存储父级的方法名，便于调用父级方法
			S.each(props, function(value, method) {
				subCls.prototype[method] = value;
				if ( typeof value === 'function' && method !== 'init') {
					subCls.prototype[method].superName = method;
				}
			});
			//添加便捷调用父级方法
			if (superCls) {
				subCls.prototype.inherit = function(args) {
					if (args.callee.superName) {
						return subCls.superclass[args.callee.superName].call(this);
					}
				}
			}
			subCls.plugins = {};
			subCls.plug = function(name, props) {
				subCls.plugins[name] = props;
			};
			subCls.unplug = function(name) {
				if (!name) {
					subCls.plugins = {};
				} else {
					subCls.plugins[name] = null;
					delete subCls.plugins[name];
				}
			};
			return subCls;
		}
	});
})(Simple);
/**
 * 为SimpleUI提供基本的事件支持，简化事件操作流程，提升响应速度，并且针对SimpleUI的组件特性加入了对node节点的disabled嗅探
 * 当该节点的的样式类中包含disabled，则不会对该操作进行响应
 * 支持二级命名空间事件命名
 * 支持面向切面的事件编程,该类被设计为用于继承的基类。
 *
 * 	var event = new Simple.EventTarget();
 * 	event.on('myblog/create',function(data){
 * 		console.log('create');
 * 	});
 *
 * 	event.on('myblog/destroy',function(){
 * 		console.log('destroy');
 * 	});
 *
 * 	event.trigger('myblog'); // will be console 'create','destroy'
 *
 * 	//面向切面
 * 	event.aspect('trigger').before(function(){
 * 		console.log('before trigger');
 * 	});
 *
 * 上面的写法等同于下面的写法
 *
 * 	Simple.aspect.before(event,'trigger',function(){
 * 		console.log('before trigger');
 * 	});
 *
 * 	event.trigger('myblog'); // will be console 'before trigger','create','destroy'
 * 	
 * @Class  EventTarget
 * 	
 */
(function(S){

	

	var aspect = (function() {
		var nextId = 0;
		function advise(dispatcher, type, advice, receiveArguments) {
			var previous = dispatcher[type];
			var around = type == "around";
			var signal;
			if (around) {
				var advised = advice(function() {
					return previous.advice(this, arguments);
				});
				signal = {
					remove: function() {
						signal.cancelled = true;
					},
					advice: function(target, args) {
						return signal.cancelled ? previous.advice(target, args) : // cancelled, skip to next one
						advised.apply(target, args); // called the advised function
					}
				};
			} else {
				// create the remove handler
				signal = {
					remove: function() {
						var previous = signal.previous;
						var next = signal.next;
						if (!next && !previous) {
							delete dispatcher[type];
						} else {
							if (previous) {
								previous.next = next;
							} else {
								dispatcher[type] = next;
							}
							if (next) {
								next.previous = previous;
							}
						}
					},
					id: nextId++,
					advice: advice,
					receiveArguments: receiveArguments
				};
			}
			if (previous && !around) {
				if (type == "after") {
					// add the listener to the end of the list
					var next = previous;
					while (next) {
						previous = next;
						next = next.next;
					}
					previous.next = signal;
					signal.previous = previous;
				} else if (type == "before") {
					// add to beginning
					dispatcher[type] = signal;
					signal.next = previous;
					previous.previous = signal;
				}
			} else {
				// around or first one just replaces
				dispatcher[type] = signal;
			}
			return signal;
		}

		function aspect(type) {
			return function(target, methodName, advice, receiveArguments) {
				var existing = target[methodName],
					dispatcher;
				if (!existing || existing.target != target) {
					// no dispatcher in place
					target[methodName] = dispatcher = function() {
						var executionId = nextId;
						// before advice
						var args = arguments;
						var before = dispatcher.before;
						while (before) {
							args = before.advice.apply(this, args) || args;
							before = before.next;
						}
						// around advice
						if (dispatcher.around) {
							var results = dispatcher.around.advice(this, args);
						}
						// after advice
						var after = dispatcher.after;
						while (after && after.id < executionId) {
							results = after.receiveArguments ? after.advice.apply(this, args) || results : after.advice.call(this, results);
							after = after.next;
						}
						return results;
					};
					if (existing) {
						dispatcher.around = {
							advice: function(target, args) {
								return existing.apply(target, args);
							}
						};
					}
					dispatcher.target = target;
				}
				var results = advise((dispatcher || existing), type, advice, receiveArguments);
				advice = null;
				return results;
			};
		}
		return {
			before: aspect("before"),
			around: aspect("around"),
			after: aspect("after")
		};
	})();


	S.declare('EventTarget', {
		init: function() {
			this.event = {};
		},
		/**
		 * 绑定一个事件，并且返回一个对象用于解绑该事件
		 * 
		 * var eventBinder = event.on('test',callback);
		 * eventBinder.off();
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Function} handle 该事件的回调函数
		 * @return {Object} 用于对这个事件进行解绑操作
		 */
		on: function(type, handle) {

			var index, _self = this,
				events = type.split('/'),
				eventPrefix, eventType, namespace, eventQueue;
			if (events.length > 1) {
				eventPrefix = events[0];
				eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {

				if (!this.event[eventPrefix]) {
					namespace = this.event[eventPrefix] = {};
				}
				if (!this.event[eventPrefix]._meta) {
					this.event[eventPrefix]._meta = [];
				}
				if (!this.event[eventPrefix][eventType]) {

					eventQueue = this.event[eventPrefix][eventType] = [];
					this.event[eventPrefix]._meta.push(handle);
				}
			} else {
				if (!this.event[eventType]) {
					eventQueue = this.event[eventType] = [];
				}
			}

			index = eventQueue.push(handle);

			return {
				off: function() {
					eventQueue.splice(index, 1);
				}
			}

		},
		/**
		 * 解除事件的绑定
		 * 
		 * var eventBinder = event.on('test',callback);
		 * event.off('test',callback)
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Function} handle 该事件的回调函数
		 * @return {Boolean} 解绑成功返回true
		 */
		off: function(type, handle) {

			var index, events = type.split('/'),
				eventPrefix, eventType, eventQueue;

			if (events.length > 1) {
				eventPrefix = events[0], eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {
				if (!this.event[eventPrefix]) {
					return true;
				} else {
					if (!this.event[eventPrefix][eventType]) {
						return true;
					} else {
						eventQueue = this.event[eventPrefix][eventType];
					}
				}
			} else {
				if (!this.event[eventType]) {
					return true;
				} else {
					eventQueue = this.event[eventType];
				}
			}

			for (var i = 0; i < eventQueue.length; i++) {
				if (eventQueue[i] === handle) {
					eventQueue.splice(i, 1);
					break;
				}
			}

			return true;

		},
		/**
		 * 触发一个事件，可以使用该事件的命名空间来触发一组事件
		 * 
		 * var eventBinder = event.on('test',callback);
		 * event.trigger('test')
		 * 
		 * @param  {String} type  事件的名称
		 * @param  {Object} args 传入该事件回调的参数
		 * @return {Boolean} 返回true
		 */
		trigger: function(type, args) {

			var index, events = type.split('/'),
				eventPrefix, eventType, eventQueue;

			if (args && args.node && /disabled/.test(args.node.attr('class'))) {
				return false;
			}

			if (events.length > 1) {
				eventPrefix = events[0], eventType = events[1];
			} else {
				eventType = events[0];
			}

			if (eventPrefix) {
				if (!this.event[eventPrefix]) {
					return true;
				}
				eventQueue = this.event[eventPrefix][eventType] || [];
			} else {
				if (this.event[eventType]) {
					if (this.event[eventType].length) {
						eventQueue = this.event[eventType];
					} else {
						if (this.event[eventType]._meta) {
							eventQueue = this.event[eventType]._meta;
						}
					}
				}
			}

			for (var i = 0; i < eventQueue.length; i++) {
				if (eventQueue[i].call(eventQueue[i], args) === false) {
					break;
				};
			}

			return true;
		},
		/**
		 * 过滤一个方法，返回一个新的方法
		 * @param  {Function} method 在过滤这个方法的时候需要执行的方法
		 * @return {Object} 返回通知的类型方法
		 */
		aspect: function(method) {
			var _self = this;
			return {
				before: function(advice, args) {
					return aspect.before(_self, method, advice, args)
				},
				after: function(advice, args) {
					return aspect.after(_self, method, advice, args)
				},
				around: function(advice, args) {
					return aspect.around(_self, method, advice, args)
				}
			}
		}
	});
	
	S.aspect = aspect;
	
})(Simple);(function (userConfig, defaultConfig, has) {
	var bd = {
		docGen : noop
	},
	req = function (config, dependencies, callback) {
		return contextRequire(config, dependencies, callback, 0, req);
	};
	req.has = has = userConfig.has || this.has || has;
	var noop = function () {},
	isEmpty = function (it) {
		for (var p in it)
			return 0;
		return 1;
	},
	toString = {}
	
	.toString,
	testPrefix = "[object ",
	functionMarker = testPrefix + "Function]",
	arrayMarker = testPrefix + "Array]",
	stringMarker = testPrefix + "String]",
	isFunction = function (it) {
		return toString.call(it) == functionMarker;
	},
	isString = function (it) {
		return toString.call(it) == stringMarker;
	},
	isArray = function (it) {
		return toString.call(it) == arrayMarker;
	},
	forEach = function (vector, callback) {
		for (var i = 0; vector && i < vector.length; )
			callback(vector[i++]);
	},
	setIns = function (set, name) {
		set[name] = 1;
	},
	setDel = function (set, name) {
		delete set[name];
	},
	mix = function (dest, src) {
		for (var p in src)
			dest[p] = src[p];
		return dest;
	},
	escapeRegEx = function (s) {
		return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function (c) {
			return "\\" + c;
		});
	},
	uidSeed = 1,
	uid = function () {
		return "_" + uidSeed++;
	},
	requested = {},
	arrived = {},
	nonmodule = {},
	pathTransforms = req.pathTransforms = [],
	paths = {},
	pathsMapProg = [],
	packages = {},
	packageMap = {},
	packageMapProg = [],
	modules = {},
	cache = {},
	computeMapProg = function (map) {
		var p,
		i,
		item,
		mapProg = [];
		for (p in map)
			mapProg.push([p, map[p]]);
		mapProg.sort(function (lhs, rhs) {
			return rhs[0].length - lhs[0].length;
		});
		for (i = 0; i < mapProg.length; ) {
			item = mapProg[i++];
			item[2] = new RegExp("^" + escapeRegEx(item[0]) + "(\/|$)");
			item[3] = item[0].length + 1;
		}
		return mapProg;
	},
	fixupPackageInfo = function (packageInfo, baseUrl) {
		baseUrl = baseUrl || "";
		packageInfo = mix({
				lib : "lib",
				main : "main",
				pathTransforms : []
			}, (isString(packageInfo) ? {
					name : packageInfo
				}
					 : packageInfo));
		packageInfo.location = baseUrl + (packageInfo.location ? packageInfo.location : packageInfo.name);
		packageInfo.mapProg = computeMapProg(packageInfo.packageMap);
		var name = packageInfo.name;
		packages[name] = packageInfo;
		packageMap[name] = name;
	},
	doWork = function (deps, callback, onLoadCallback) {
		((deps && deps.length) || callback) && req(deps || [], callback || noop);
		onLoadCallback && req.ready(onLoadCallback);
	},
	config = function (config, booting) {
		var p,
		i,
		transforms;
		for (p in config)
			if (!/pathTransforms|paths|packages|packageMap|packagePaths|cache|ready/.test(p)) {
				req[p] = config[p];
			};
		if (!req.baseUrl) {
			req.baseUrl = "./";
		} else if (!/\/$/.test(req.baseUrl)) {
			req.baseUrl += "/";
		}
		for (transforms = config.pathTransforms, i = 0; transforms && i < transforms.length; i++) {
			pathTransforms.push(transforms[i]);
		}
		pathsMapProg = computeMapProg(mix(paths, config.paths));
		forEach(config.packages, fixupPackageInfo);
		for (baseUrl in config.packagePaths) {
			forEach(config.packagePaths[baseUrl], function (packageInfo) {
				fixupPackageInfo(packageInfo, baseUrl + "/");
			});
		}
		packageMapProg = computeMapProg(mix(packageMap, config.packageMap));
		mix(cache, config.cache);
		if (!booting) {
			doWork(config.deps, config.callback, config.ready);
		}
	};
	config(defaultConfig, 1);
	config(userConfig, 1);
	if (has("loader-node")) {
		if (isFunction(global.define)) {
			console.log("global define already defined; did you try to load multiple AMD loaders?");
			return;
		}
	} else {
		if (isFunction(this.define)) {
			console.error("global define already defined; did you try to load multiple AMD loaders?");
			return;
		}
	}
	var
	injectDependencies = function (module) {
		forEach(module.deps, injectModule);
	},
	contextRequire = function (a1, a2, a3, referenceModule, contextRequire) {
		var module,
		syntheticMid;
		if (isString(a1)) {
			module = getModule(a1, referenceModule);
			if (module.plugin) {
				injectPlugin(module, true);
			}
			return module.result;
		}
		if (!isArray(a1)) {
			config(a1);
			a1 = a2;
			a2 = a3;
		}
		if (isArray(a1)) {
			for (var i = 0; i < a1.length; i++) {
				a1[i] = getModule(a1[i], referenceModule);
			}
			syntheticMid = uid();
			module = mix(makeModuleInfo("", syntheticMid, "*" + syntheticMid, 0, "", ""), {
					injected : arrived,
					deps : a1,
					def : a2 || noop
				});
			injectDependencies(module);
			if (execModule(module) === abortExec) {
				execQ.push(module);
			}
		}
		return contextRequire;
	},
	createRequire = function (module) {
		var result = module.require;
		if (!result) {
			result = function (a1, a2, a3) {
				return contextRequire(a1, a2, a3, module, result);
			};
			module.require = mix(result, req);
			result.nameToUrl = result.toUrl = function (name, ext) {
				return nameToUrl(name, ext, module);
			};
			result.toAbsMid = function (mid) {
				return getModuleInfo(mid, module, packages, modules, req.baseUrl, ".", packageMapProg, pathsMapProg, pathTransforms).path;
			};
			if (has("loader-undefApi")) {
				result.undef = function (moduleId) {
					var
					module = getModule(moduleId, module),
					pqn = module.pqn;
					setDel(modules, pqn);
					setDel(waiting, pqn);
					setDel(injectedUrls, module.url);
				};
			}
		}
		return result;
	},
	execQ = [],
	waiting = {},
	execComplete = function () {
		return defQ && !defQ.length && isEmpty(waiting) && !execQ.length;
	},
	runMapProg = function (targetMid, map) {
		for (var i = 0; i < map.length; i++) {
			if (map[i][2].test(targetMid)) {
				return map[i];
			}
		}
		return 0;
	},
	compactPath = function (path) {
		while (/\/\.\//.test(path))
			path = path.replace(/\/\.\//, "/");
		path = path.replace(/(.*)\/\.$/, "$1");
		while (/[^\/\.]+\/\.\./.test(path))
			path = path.replace(/[^\/]+\/\.\.\/?/, "");
		return path;
	},
	transformPath = function (path, transforms) {
		for (var i = 0, result = 0, item; !result && i < transforms.length; ) {
			item = transforms[i++];
			if (isFunction(item)) {
				result = item(path);
			} else {
				result = item[0].test(path) && path.replace(item[0], item[1]);
			}
		}
		return result;
	},
	makeModuleInfo = function (pid, mid, pqn, pack, path, url) {
		var result = {
			pid : pid,
			mid : mid,
			pqn : pqn,
			pack : pack,
			path : path,
			url : url
		};
		return result;
	},
	getModuleInfo = function (mid, referenceModule, packages, modules, baseUrl, pageUrl, packageMapProg, pathsMapProg, pathTransforms, alwaysCreate) {
		var pid,
		pack,
		pqn,
		mapProg,
		mapItem,
		path,
		url,
		result;
		if (/(^\/)|(\:)|(\.[^\/]+$)/.test(mid)) {
			url = /^\./.test(mid) ? compactPath(pageUrl + "/" + mid) : mid;
			return makeModuleInfo(0, url, "*" + url, 0, url, url);
		} else {
			if (/^\./.test(mid)) {
				mid = referenceModule ? referenceModule.path + "/../" + mid : baseUrl + mid;
			}
			path = compactPath(mid);
			mapProg = referenceModule && referenceModule.pack && referenceModule.pack.mapProg;
			mapItem = (mapProg && runMapProg(path, mapProg)) || runMapProg(path, packageMapProg);
			if (mapItem) {
				pid = mapItem[1];
				mid = path.substring(mapItem[3]);
			} else {
				pid = "";
				mid = path;
			}
			pqn = pid + "*" + mid;
			result = modules[pqn];
			if (result) {
				return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pqn, result.pack, result.path, result.url) : modules[pqn];
			}
		}
		if (pid) {
			pack = packages[pid];
			path = pid + "/" + (mid || pack.main);
			url = pack.location + "/" + (pack.lib ? pack.lib + "/" : "") + (mid || pack.main);
			mapItem = runMapProg(url, pathsMapProg);
			if (mapItem) {
				url = mapItem[1] + url.substring(mapItem[3] - 1);
			} else {
				url = transformPath(path, pack.pathTransforms) || url;
			}
		} else {
			mapItem = runMapProg(path, pathsMapProg);
			if (mapItem) {
				url = mapItem[1] + path.substring(mapItem[3] - 1);
			} else {
				url = transformPath(path, pathTransforms) || path;
			}
		}
		if (!(/(^\/)|(\:)/.test(url))) {
			url = baseUrl + url;
		}
		url += ".js";
		return makeModuleInfo(pid, mid, pqn, pack, path, compactPath(url));
	},
	getModule = function (mid, referenceModule) {
		var match,
		plugin,
		pluginResource,
		result,
		existing,
		pqn;
		match = mid.match(/^(.+?)\!(.+)$/);
		if (match) {
			plugin = getModule(match[1], referenceModule),
			pluginResource = match[2];
			pqn = plugin.pqn + "!" + (referenceModule ? referenceModule.pqn + "!" : "") + pluginResource;
			return modules[pqn] || (modules[pqn] = {
					plugin : plugin,
					mid : pluginResource,
					req : (referenceModule ? createRequire(referenceModule) : req),
					pqn : pqn
				});
		} else {
			result = getModuleInfo(mid, referenceModule, packages, modules, req.baseUrl, ".", packageMapProg, pathsMapProg, pathTransforms);
			return modules[result.pqn] || (modules[result.pqn] = result);
		}
	},
	nameToUrl = req.nameToUrl = req.toUrl = function (name, ext, referenceModule) {
		var
		match = name.match(/(.+)(\.[^\/]+)$/),
		url = getModuleInfo(match && match[1] || name, referenceModule, packages, modules, req.baseUrl, ".", packageMapProg, pathsMapProg, pathTransforms).url;
		return url.substring(0, url.length - 3) + (ext ? ext : (match ? match[2] : ""));
	},
	cjsModuleInfo = {
		injected : arrived,
		deps : [],
		executed : 1,
		result : 1
	},
	cjsRequireModule = mix(getModule("require"), cjsModuleInfo),
	cjsExportsModule = mix(getModule("exports"), cjsModuleInfo),
	cjsModuleModule = mix(getModule("module"), cjsModuleInfo),
	ranFactory = 0,
	runFactory = function (pqn, factory, args, cjs) {
		if (has("loader-traceApi")) {
			req.trace("loader-runFactory", [pqn]);
		}
		ranFactory = 1;
		return isFunction(factory) ? (factory.apply(null, args) || (cjs && cjs.exports)) : factory;
	},
	abortExec = {},
	evalOrder = 0,
	execModule = function (module) {
		if (!module.executed) {
			if (typeof module.def == "undefined") {
				return abortExec;
			}
			var
			pqn = module.pqn,
			deps = module.deps || [],
			arg,
			argResult,
			args = [],
			i = 0;
			if (has("loader-traceApi")) {
				req.trace("loader-execModule", [pqn]);
			}
			module.executed = 1;
			while (i < deps.length) {
				arg = deps[i++];
				argResult = ((arg === cjsRequireModule) ? createRequire(module) : ((arg === cjsExportsModule) ? module.exports : ((arg === cjsModuleModule) ? module : execModule(arg))));
				if (argResult === abortExec) {
					module.executed = 0;
					return abortExec;
				}
				args.push(argResult);
			}
			if (has("loader-catchApi")) {
				try {
					module.result = runFactory(pqn, module.def, args, module.cjs);
				} catch (e) {
					if (!has("loader-errorApi") || !req.onError("loader/exec", [e, pqn].concat(args))) {
						throw e;
					}
				}
			} else {
				module.result = runFactory(pqn, module.def, args, module.cjs);
			}
			module.evalOrder = evalOrder++;
			if (module.loadQ) {
				var
				q = module.loadQ,
				load = module.load = module.result.load;
				while (q.length) {
					load.apply(null, q.shift());
				}
			}
			if (has("loader-traceApi")) {
				req.trace("loader-execModule-out", [pqn]);
			}
		}
		return module.result;
	},
	checkCompleteRecursiveGuard = 0,
	checkComplete = function () {
		if (checkCompleteRecursiveGuard) {
			return;
		}
		checkCompleteRecursiveGuard = 1;
		ranFactory = 1;
		while (ranFactory) {
			ranFactory = 0;
			for (var result, i = 0; i < execQ.length; ) {
				result = execModule(execQ[i]);
				if (result !== abortExec) {
					execQ.splice(i, 1);
				} else {
					i++;
				}
			}
		}
		checkCompleteRecursiveGuard = 0;
		if (has("loader-pageLoadApi")) {
			onLoad();
		}
	};
	req.toAbsMid = function (id) {
		return id;
	};
	if (has("loader-undefApi")) {
		req.undef = function (moduleId) {
			var
			module = getModule(moduleId, 0),
			pqn = module.pqn;
			setDel(modules, pqn);
			setDel(waiting, pqn);
			setDel(injectedUrls, module.url);
		};
	}
	if (has("loader-traceApi")) {
		var
		symbols = {},
		symbol = function (name) {
			return symbols[name] || (symbols[name] = {
					value : name
				});
		};
		requested = symbol("requested");
		arrived = symbol("arrived");
		nonmodule = symbol("not-a-module");
	}
	if (has("loader-injectApi")) {
		var
		injectedUrls = {},
		injectPlugin = function (module, immediate) {
			var
			pqn = module.pqn,
			onload = function (def) {
				mix(module, {
					executed : 1,
					result : def
				});
				setDel(waiting, pqn);
				checkComplete();
			};
			if (cache[pqn]) {
				onload(cache[pqn]);
			} else {
				var plugin = module.plugin;
				if (!plugin.load) {
					if (plugin.executed) {
						plugin.load = plugin.result.load;
					} else if (!immediate) {
						plugin.loadQ = [];
						plugin.load = function (id, require, callback) {
							plugin.loadQ.push([id, require, callback]);
						};
						injectModule(plugin);
						execQ.unshift(plugin);
					}
				}
				!immediate && setIns(waiting, pqn);
				plugin.load && plugin.load(module.mid, module.req, onload);
			}
		},
		injecting = [],
		injectModule = function (module) {
			var pqn = module.pqn;
			if (module.injected || waiting[pqn]) {
				return;
			}
			if (module.plugin) {
				injectPlugin(module);
				return;
			}
			module.injected = requested;
			setIns(waiting, pqn);
			var url = module.url;
			if (injectedUrls[url]) {
				return;
			}
			injectedUrls[url] = requested;
			var onLoadCallback = function () {
				injectedUrls[url] = arrived;
				setDel(waiting, pqn);
				runDefQ(module);
				if (module.injected !== arrived) {
					mix(module, {
						injected : arrived,
						deps : [],
						def : nonmodule,
						result : nonmodule
					});
				}
				checkComplete();
			};
			if (cache[pqn]) {
				injecting.push(module);
				cache[pqn].call(null);
				injecting.pop();
				onLoadCallback();
			} else {
				injecting.push(module);
				module.node = req.injectUrl(url, onLoadCallback);
				injecting.pop();
				startTimer();
			}
		},
		defQ = [],
		defineModule = function (module, deps, def) {
			if (has("loader-traceApi")) {
				req.trace("loader-defineModule", [module, deps]);
			}
			var pqn = module.pqn;
			if (module.injected == arrived) {
				req.onError("loader/multiple-define", [pqn]);
				return module;
			}
			mix(module, {
				injected : arrived,
				deps : deps,
				def : def,
				cjs : {
					id : module.path,
					uri : module.url,
					exports : (module.result = {}),
					setExports : function (exports) {
						module.cjs.exports = exports;
					}
				}
			});
			for (var i = 0; i < deps.length; i++) {
				deps[i] = getModule(deps[i], module);
			}
			setDel(waiting, pqn);
			return module;
		},
		runDefQ = function (referenceModule) {
			var
			definedModules = [],
			module,
			args;
			while (defQ.length) {
				args = defQ.shift();
				module = args[0] && getModule(args[0]) || referenceModule;
				definedModules.push(defineModule(module, args[1], args[2]));
			}
			forEach(definedModules, injectDependencies);
		};
	}
	if (has("loader-timeoutApi")) {
		var
		timerId = 0,
		clearTimer = function () {
			timerId && clearTimeout(timerId);
			timerId = 0;
		},
		startTimer = function () {
			clearTimer();
			req.timeout && (timerId = setTimeout(function () {
						clearTimer();
						req.onError("loader/timeout", [waiting]);
					}, req.timeout));
		};
	} else {
		var
		clearTimer = noop,
		startTimer = noop;
	}
	if (has("dom")) {
		var doc = document;
		if (has("loader-pageLoadApi") || has("loader-injectApi")) {
			var on = function (node, eventName, handler, useCapture, ieEventName) {
				if (has("dom-addEventListener")) {
					node.addEventListener(eventName, handler, !!useCapture);
					return function () {
						node.removeEventListener(eventName, handler, !!useCapture);
					};
				} else {
					if (ieEventName !== false) {
						eventName = ieEventName || "on" + eventName;
						node.attachEvent(eventName, handler);
						return function () {
							node.detachEvent(eventName, handler);
						};
					} else {
						return noop;
					}
				}
			};
		}
		if (has("loader-injectApi")) {
			var head = doc.getElementsByTagName("head")[0] || doc.getElementsByTagName("html")[0];
			req.injectUrl = req.injectUrl || function (url, callback) {
				var
				node = doc.createElement("script"),
				onLoad = function (e) {
					e = e || window.event;
					var node = e.target || e.srcElement;
					if (e.type === "load" || /complete|loaded/.test(node.readyState)) {
						disconnector();
						callback && callback();
					}
				},
				disconnector = on(node, "load", onLoad, false, "onreadystatechange");
				node.src = url;
				node.type = "text/javascript";
				node.charset = "utf-8";
				head.appendChild(node);
				return node;
			};
		}
		if (has("loader-sniffApi")) {
			if (!req.baseUrl) {
				req.baseUrl = "";
				for (var match, src, dataMain, scripts = doc.getElementsByTagName("script"), i = 0; i < scripts.length; i++) {
					src = scripts[i].getAttribute("src") || "";
					if ((match = src.match(/require\.js$/))) {
						req.baseUrl = src.substring(0, match.index) || "./";
						dataMain = scripts[i].getAttribute("data-main");
						if (dataMain) {
							req.deps = req.deps || [dataMain];
						}
						req.baseNode = scripts[i];
						break;
					}
				}
			}
		}
		if (has("loader-pageLoadApi")) {
			req.pageLoaded = req.pageLoaded || document.readyState == "complete";
			if (!req.pageLoaded) {
				var
				loadDisconnector = 0,
				DOMContentLoadedDisconnector = 0,
				scrollIntervalId = 0,
				detectPageLoadedFired = 0,
				detectPageLoaded = function () {
					if (detectPageLoadedFired) {
						return;
					}
					detectPageLoadedFired = 1;
					if (scrollIntervalId) {
						clearInterval(scrollIntervalId);
						scrollIntervalId = 0;
					}
					loadDisconnector && loadDisconnector();
					DOMContentLoadedDisconnector && DOMContentLoadedDisconnector();
					req.pageLoaded = true;
					onLoad();
				};
				if (!req.pageLoaded) {
					loadDisconnector = on(window, "load", detectPageLoaded, false);
					DOMContentLoadedDisconnector = on(doc, "DOMContentLoaded", detectPageLoaded, false, false);
				}
				if (!has("dom-addEventListener")) {
					if (self === self.top) {
						scrollIntervalId = setInterval(function () {
								try {
									if (doc.body) {
										doc.documentElement.doScroll("left");
										detectPageLoaded();
									}
								} catch (e) {}
								
							}, 30);
					}
				}
			}
			var
			loadQ = [],
			onLoadRecursiveGuard = 0,
			onLoad = function () {
				while (execComplete() && !checkCompleteRecursiveGuard && !onLoadRecursiveGuard && req.pageLoaded && loadQ.length) {
					onLoadRecursiveGuard = true;
					var f = loadQ.shift();
					if (has("loader-catchApi")) {
						try {
							f();
						} catch (e) {
							onLoadRecursiveGuard = 0;
							if (!req.onError("loader/onLoad", [e])) {
								throw e;
							}
						}
					} else {
						f();
					}
					onLoadRecursiveGuard = 0;
				}
			};
			req.ready = function (context, callback) {
				if (callback) {
					loadQ.push(isString(callback) ? function () {
						context[callback]();
					}
						 : function () {
						callback.call(context);
					});
				} else {
					loadQ.push(context);
				}
				onLoad();
			};
		} else {
			req.ready = noop;
		}
	}
	if (has("loader-traceApi")) {
		req.trace = function (group, args) {
			if (req.traceSet[group]) {
				if (has("console-log-apply")) {
					console.log.apply(console, [group + ": "].concat(args));
				} else {
					for (var i = 0; i < args.length; i++) {
						console.log(args[i]);
					}
				}
			}
		};
	} else {
		req.trace = req.trace || noop;
	}
	if (has("loader-errorApi")) {
		var onError = req.onError = function (messageId, args) {
			for (var errorbacks = onError.listeners, result = false, i = 0; i < errorbacks.length; i++) {
				result = result || errorbacks[i](messageId, args);
			}
			console.error(messageId, args);
			onError.log.push(args);
			return result;
		};
		onError.listeners = [];
		onError.log = [];
	} else {
		req.onError = req.onError || noop;
	}
	var def = function (mid, dependencies, factory) {
		var
		arity = arguments.length,
		args = 0,
		defaultDeps = ["require", "exports", "module"];
		if (arity == 3 && dependencies == 0) {
			execModule(defineModule(getModule(mid), [], factory));
			return;
		}
		if (has("loader-amdFactoryScan")) {
			if (arity == 1) {
				dependencies = [];
				mid.toString().replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "").replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function (match, dep) {
					dependencies.push(dep);
				});
				args = [0, defaultDeps.concat(dependencies), mid];
			}
		}
		if (!args) {
			args = arity == 1 ? [0, defaultDeps, mid] : (arity == 2 ? (isArray(mid) ? [0, mid, dependencies] : [mid, defaultDeps, dependencies]) : [mid, dependencies, factory]);
		}
		if (has("loader-traceApi")) {
			req.trace("loader-define", args.slice(0, 2));
		}
		if (args[0]) {
			injectDependencies(defineModule(getModule(args[0]), args[1], args[2]));
		} else {
			if (has("dom-addEventListener") || has("loader-node")) {
				defQ.push(args);
			} else {
				var
				length = injecting.length,
				targetModule = length && injecting[length - 1],
				pqn,
				module;
				if (!targetModule) {
					for (pqn in waiting) {
						module = modules[pqn];
						if (module.node && module.node.readyState === 'interactive') {
							targetModule = module;
							break;
						}
					}
				}
				if (targetModule) {
					injectDependencies(defineModule(targetModule, args[1], args[2]));
				} else {
					req.onError("loader/define-ie");
				}
			}
		}
	};
	if (has("loader-createHasModule")) {
		mix(getModule("has"), {
			injected : arrived,
			deps : [],
			executed : 1,
			result : has
		});
	}
	if (has("loader-publish-privates")) {
		mix(req, {
			isEmpty : isEmpty,
			isFunction : isFunction,
			isString : isString,
			isArray : isArray,
			forEach : forEach,
			setIns : setIns,
			setDel : setDel,
			mix : mix,
			uid : uid,
			on : on,
			paths : paths,
			packages : packages,
			modules : modules,
			execQ : execQ,
			defQ : defQ,
			waiting : waiting,
			injectedUrls : injectedUrls,
			loadQ : loadQ,
			computeMapProg : computeMapProg,
			runMapProg : runMapProg,
			compactPath : compactPath,
			transformPath : transformPath,
			getModuleInfo : getModuleInfo
		});
	}
	if (has("loader-node")) {
		def.require = req;
		global.define = def;
		req.deps = req.deps || [];
	} else {
		define = def;
		require = req;
	}
	if (has("loader-requirejsApi")) {
		req.def = define;
	}
	if (has("loader-injectApi")) {
		doWork(req.deps, req.callback, userConfig.ready);
	} else {
		(function () {
			var p;
			for (p in cache) {
				modules[p] = cache[p];
			}
			for (p in cache) {
				var module = modules[p];
				module.pqn = p;
				for (var i = 0; i < deps.length; i++) {
					deps[i] = getModule(deps[i], module);
				}
				execQ.push(module);
			}
			doCheckComplete();
		})();
	}
})
(this.require || {}, {
	vendor : "altoviso.com",
	version : "1.0-beta",
	baseUrl : ".",
	host : "browser",
	isBrowser : 1,
	timeout : 0,
	traceSet : {
		"loader-define" : 0,
		"loader-runFactory" : 0,
		"loader-execModule" : 0,
		"loader-execModule-out" : 0,
		"loader-defineModule" : 0
	}
}, (function () {
		var
		global = this,
		doc = document,
		element = doc.createElement("div"),
		cache = {
			"dom" : 1,
			"dom-addEventListener" : !!document.addEventListener,
			"console" : typeof console != "undefined",
			"console-log-apply" : !!(typeof console != "undefined" && console.log && console.log.apply),
			"loader-injectApi" : 1,
			"loader-timeoutApi" : 1,
			"loader-traceApi" : 1,
			"loader-catchApi" : 1,
			"loader-pageLoadApi" : 1,
			"loader-errorApi" : 1,
			"loader-sniffApi" : 0,
			"loader-undefApi" : 0,
			"loader-requirejsApi" : 1,
			"loader-createHasModule" : 1,
			"loader-amdFactoryScan" : 1,
			"loader-publish-privates" : 1,
			"native-xhr" : !!this.XMLHttpRequest
		},
		has = function (name) {
			if (typeof cache[name] == "function") {
				cache[name] = cache[name](global, doc, element);
			}
			return cache[name];
		};
		has.cache = cache;
		has.add = function (name, test, now) {
			cache[name] = now ? test(global, doc, element) : test;
		};
		if (this.has) {
			has = this.has;
			for (var p in cache) {
				has.add(p, function () {
					return cach[p];
				}, 1);
			}
		}
		return has;
	})());
